<template>
	<Upload
		v-bind="bindValue"
		v-model:value="responseList"
		v-model:fileList="imgListRef"
		accept="image/*"
		list-type="picture-card"
		:before-upload="beforeUpload"
		:showUploadList="{ showPreviewIcon: false, showRemoveIcon: true }"
		@change="handleChange"
	>
		<div v-if="imgListRef.length < maxNumber">
			<PlusOutlined />
			<div class="ant-upload-text">Upload</div>
		</div>
	</Upload>
</template>
<script lang="ts">
import { computed, defineComponent, ref, watch } from 'vue';
import { PlusOutlined } from '@ant-design/icons-vue';
import { Upload } from 'ant-design-vue';
import type { UploadChangeParam } from 'ant-design-vue/lib/upload/interface';
import { useMessage } from '@/hooks/web/useMessage';
import { isFunction } from '@/utils/is';
import { omit } from 'lodash-es';
import { pictureCardUploadProps } from '../props';

export default defineComponent({
	name: 'PictureCardUpload',
	components: { Upload, PlusOutlined },
	props: pictureCardUploadProps,
	emits: ['change', 'update:value'],
	setup(props, { attrs, emit }) {
		const imgListRef = ref<Recordable[]>([]);
		let responseList = ref<Recordable[]>([]);

		const { createMessage } = useMessage();

		const bindValue = computed(() => {
			const value = { ...attrs, ...props };
			return omit(value, 'onChange');
		});

		watch(
			() => props.value,
			value => {
				!value.length && (imgListRef.value = []);
			},
			{ immediate: true },
		);

		function beforeUpload(file: File) {
			const { maxSize } = props;
			// 设置最大值，则判断
			if (maxSize && file.size / 1024 / 1024 >= maxSize) {
				createMessage.error(`只能上传不超过${maxSize}MB的文件`);
			}
			return false;
		}

		async function handleChange({ file }: UploadChangeParam) {
			const { api } = props;
			if (!api || !isFunction(api)) {
				return console.warn('upload api must exist and be a function');
			}

			if (file.status === 'removed') {
				handleRemove(file);
				return;
			}
			try {
				const data = await props.api?.({
					data: {
						...(props.uploadParams || {}),
					},
					file: file,
				});
				responseList.value.push({ file, responseData: data });

				const rs = responseList.value.map(i => i.responseData);
				emit('update:value', rs);
				emit('change', rs);
			} catch (e) {
				return {
					success: false,
					error: e,
				};
			}
		}

		function handleRemove(file: any) {
			const index = responseList.value.findIndex(item => item.file.uid === file.uid);
			index !== -1 && responseList.value.splice(index, 1);

			const rs = responseList.value.map(i => i.responseData);
			emit('update:value', rs);
			emit('change', rs);
		}

		return {
			imgListRef: imgListRef as any,
			responseList,
			bindValue,
			beforeUpload,
			handleChange,
		};
	},
});
</script>
<style lang="less" scoped>
.ant-upload-select-picture-card {
	i {
		font-size: 32px;
		color: #999;
	}
	.ant-upload-text {
		margin-top: 8px;
		color: #666;
	}
}
</style>
